#ifndef GRAPHICENGINE_H
#define GRAPHICENGINE_H

#include <App.h>
#include "../Model/AppList.h"
#include "../Model/SystemPreferences.h"

class GraphicEngine {
private:
  /**
   * common initializations in constructors
   */
  void init(int* argc, char ** argv);

public:
  /**
   * Creates a new GraphicEngine
   * Can be constructed one time only
   * @param velocity sets the velocity of the annimation
   * @param angle
   * @param rotation
   * @param workingApps the applist that contains the apps to display
   * @param argc arg from the main function
   * @param argv arg from the main function
   */
  GraphicEngine(float velocity, float translate, float lateralBackTranslate,
      float lateralHorizontalTranslate, float rotation, int xRes, int yRes, int colorDepth,
      AppList* workingList,
      int* argc, char ** argv);

  /**
   * Creates a new GraphicEngine with preferences
   * Can be constructed one time only
   * @param prefs set the system preferences model
   * @param workingApps the applist that contains the apps to display
   * @param argc arg from the main function
   * @param argv arg from the main function
   */
  GraphicEngine(SystemPreferences prefs, AppList* workingList, int* argc,
      char ** argv);

  /**
   * Destructor
   */
  ~GraphicEngine();

  /**
   * Open the screen
   */
  void start();

  /**
   * Refresh the screen if needed
   */
  void refresh();

  /**
   * Draw the three main apps
   */
  void draw();

  /**
   * Begin and draw a left rotating transformation
   * Do not modify the AppList
   */
  void rotateLeft();

  /**
   * Begin and draw a right rotating transformation
   * Do not modify the AppList
   */
  void rotateRight();

  /**
   * Called by rotateLeft()
   * effective draw of the transition
   */
  void drawRotateLeft();

  /**
   * Called by rotateRight()
   * effective draw of the transition
   */
  void drawRotateRight();

  /**
   * @return the session state {
   */
  bool sessionState();

  /**
   * Activate the session (on keyboard press or move detection
   */
  void activateSession();

  /**
   * Desactivate the session
   */
  void desactivateSession();

  /**
   * Draw the dock
   */
  void drawDock();

  /**
   * Common GL code (init and camera setup)
   */
  void commonGL();

  /**
   * getter for x resolution
   */
  int getXRes();

  /**
   * getter for x resolution
   */
  int getYRes();

private:
  void drawApp(float x_translate, float y_translate, float z_translate,
      float delta_rotate, float axis_x_rotate, float axis_y_rotate,
      float axis_z_rotate, App* appToDraw, int state);

  /**
   * Draw the floor for reflexion
   */
  void drawFloor();

  int _velocity; /** Velocity of animation in ms */
  float _backTranslate; /** back translation of central app */
  float _lateralTranslate; /** back translation of lateral apps */
  float _leftAndRightTranslate; /** space between central and lateral apps */
  float _leftAndRightRotate;  /** angle of lateral apps */
  int _time; /** time of the beginning of animation */
  bool _sessionActive; /** give the state of the session */
  int _xRes; /** x resolution of the display in pixels */
  int _yRes; /** y resolution of the display in pixels */
  int _colorDepth; /** color resolution of the display in bits */
  App* _leftApp; /** left App displayed */
  App* _middleApp; /** central (main) App displayed */
  App* _rightApp; /** right App displayed*/
  App* _replacingApp; /** entering app during transitions */
  AppList* _appList; /** workingApplist */

};

#endif
